/**
 * 
 */
package supermemo.input;

/**
 * @author qyan
 * Note this class borrows idea from the code in 
 * 	http://www.superliminal.com/sources/Pair.java.html.
 */
public class Pair<TYPE1, TYPE2> 
{
    public TYPE1 o1;
    public TYPE2 o2;
    
    public Pair(TYPE1 o1, TYPE2 o2) 
    { 
    	this.o1 = o1; this.o2 = o2; 
    }

    public TYPE1 first()
    {
    	return o1;
    }
    
    public TYPE2 second()
    {
    	return o2;
    }
    
    
    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     * Note, I don't know if it works well. Maybe in some tricky case, collision may happen.
     */
    public int hashCode() 
    {
        int code = 0;
        if(o1 != null)
            code = o1.hashCode();
        if(o2 != null)
            code = code/2 + o2.hashCode()/2;
        return code;
    }

    public static boolean same(Object o1, Object o2) 
    {
        return o1 == null ? o2 == null : o1.equals(o2);
    }

    public boolean equals(Object obj) 
    {
        if( ! (obj instanceof Pair))
            return false;
        Pair p = (Pair)obj;
        return same(p.o1, this.o1) && same(p.o2, this.o2);
    }

    public String toString() 
    {
        return "Pair{"+o1+", "+o2+"}";
    }

    /**
     * Simple example test program.
     */
    public static void main(String[] args) {
        Pair<String, String>
            p1 = new Pair<String, String>("a", "b"),
            p2 = new Pair<String, String>("a", null),
            p3 = new Pair<String, String>("a", "b"),
            p4 = new Pair<String, String>(null, null);
        System.out.println(p1.equals(new Pair<Integer, Integer>(1, 2)) + " should be false");
        System.out.println(p4.equals(p2) + " should be false");
        System.out.println(p2.equals(p4) + " should be false");
        System.out.println(p1.equals(p3) + " should be true");
        System.out.println(p4.equals(p4) + " should be true");
    }

}